#include "CountExceptionChecker.h"
#include "BasicType.h"
#include <algorithm>
#include <functional>
#include <math.h>

CountExceptionChecker::CountExceptionChecker():
    m_maxChange(1),
    m_duration(1)
{

}

CountExceptionChecker& CountExceptionChecker::setThreshold(int maxChange, int duration)
{
    if (maxChange > 0)
    {
        m_maxChange = maxChange;
    }

    if (duration > 0)
    {
        m_duration = duration;
    }

    return *this;
}

bool CountExceptionChecker::check(int count, TimedCount& dif)
{
	bool found = false;

	int64_t curTime = getTime();
    TimedCount timedCount(curTime, count);

    clearExpired(curTime - m_duration);

	TimedCountQueue::reverse_iterator it = m_timedCountQueue.rbegin();
	for (; it != m_timedCountQueue.rend(); ++it)
	{
		int changed = abs(it->second - count);
		if (changed >= m_maxChange)
		{
			dif.first = curTime - it->first;
			dif.second = changed;
			found = true;
			break;
		}
	}

    m_timedCountQueue.push_back(timedCount);

	return found;
}

void CountExceptionChecker::clear()
{
    m_timedCountQueue.clear();
}

int64_t CountExceptionChecker::getTime()
{
    return GetTickCount();
}

void CountExceptionChecker::clearExpired(int64_t ts)
{
	if (m_timedCountQueue.size() > 0)
	{
		auto filter = [=](const TimedCount& timedCount) { return (timedCount.first < ts); };
		TimedCountQueue::iterator itEnd = std::remove_if(m_timedCountQueue.begin(), m_timedCountQueue.end(), filter);
		m_timedCountQueue.erase(itEnd, m_timedCountQueue.end());
	}
}
